﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Media.Imaging;
using iMapa.Backend;
using iMapa.Utils;
using System.Windows;
using Emgu.CV.Structure;
using iMapa.UI.ModelView.Editor;
using System.Collections.ObjectModel;
using System.Collections;
using iMapa.UI.ModelView.Common;

namespace iMapa.UI.ModelView.Main
{
    public class MapViewModel: INotifyPropertyChanged
    {
        InteractMap imap;
        BitmapSource image;
        BitmapSource grayImage;
        MainViewModel root;
        ObservableCollection<InteractObjectViewModel> iObjectVMs ;
        List<ActionTypeViewModel> plugins;
        InteractObjectViewModel selectedIObj;

        Size displaySize;

        public MapViewModel(MainViewModel root, InteractMap map)
        {
            this.root = root;
            this.imap = map;
            iObjectVMs = CreateIObjVMList();
        }

        public BitmapSource Image
        {
            get { return image; }
            set { image = value; }
        }


        public String Name
        {
            get { return imap.Name; }
            set { imap.Name = value; }
        }
        
        public InteractMap Imap
        {
            get { return imap; }
            set { imap = value; }
        }

        public Boolean IsCalibrated
        {
            get { return imap.HMatrixToObserved != null; }
        }

        public MainViewModel Root
        {
            get { return root; }
            set { root = value; }
        }

        public bool IsSelected
        {
            get { return SelectedIObj!=null;}
        }

        public BitmapSource GrayImage
        {
            get {
                if (grayImage == null)
                {
                    grayImage = ImgUtils.ToBitmapSource(imap.ModelImage.Convert<Gray, Byte>());
                }
                return grayImage; 
            }
        }

        public Visibility CalibratedVisibility
        {
            get { return IsCalibrated ? Visibility.Visible : Visibility.Hidden; }
        }

        public Visibility NotCalibratedVisibility
        {
            get { return IsCalibrated ? Visibility.Hidden : Visibility.Visible; }
        }

        public ObservableCollection<InteractObjectViewModel> IObjectVMs
        {
            get
            {
                return iObjectVMs;
            }
            set { iObjectVMs = value; }
        }

        public InteractObjectViewModel AddPoint()
        {
            InteractObject iobj = new InteractObject();
            iobj.MapName = this.Name;
            iobj.Name = "Enter name...";
            imap.InteractObjects.Add(iobj);
            InteractObjectViewModel iovm = new InteractObjectViewModel(root, iobj, this);
            iovm.Radius = 10;
            iObjectVMs.Add(iovm);
            return iovm;
        }

        public void RemovePoint(InteractObjectViewModel iovm)
        {
            iObjectVMs.Remove(iovm);
            imap.InteractObjects.Remove(iovm.IObject);
        }

        private ObservableCollection<InteractObjectViewModel> CreateIObjVMList()
        {
            ObservableCollection<InteractObjectViewModel> result = new ObservableCollection<InteractObjectViewModel>();
            foreach (InteractObject io in imap.InteractObjects)
            {
                result.Add(new InteractObjectViewModel(root,io, this));
            }
            return result;
        }

        public InteractObjectViewModel SelectedIObj
        {
            get { return selectedIObj; }
            set
            {
                InteractObjectViewModel oldSelection=selectedIObj;
                selectedIObj = value;
                onPropertyChanged("SelectedIObj");
                onPropertyChanged("iObjectVMs");
                onPropertyChanged("IsSelected");
                if (oldSelection != null)
                {
                    oldSelection.onPropertyChanged("IsSelected");
                }
            }
        }

        public List<ActionTypeViewModel> Plugins
        {
            get
            {
                if (plugins == null)
                {
                    plugins = ActionTypeViewModel.CreateActionTypesList();
                }
                return plugins;
            }
        }

        public void onCalibrationChanged()
        {
            onPropertyChanged("NotCalibratedVisibility");
            onPropertyChanged("CalibratedVisibility");
            onPropertyChanged("IsCalibrated");
        }

        public Size DisplaySize
        {
            get { return displaySize; }
            set { displaySize = value;
                foreach (InteractObjectViewModel io in iObjectVMs){
                    io.onPropertyChanged("Radius");
                    io.onPropertyChanged("RadiusShow");
                    io.onPropertyChanged("Offset");
                    io.onPropertyChanged("TextOffset");
                    io.onPropertyChanged("Y");
                    io.onPropertyChanged("Yreal");
                    io.onPropertyChanged("X");
                    io.onPropertyChanged("Xreal");
                }
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        public void onPropertyChanged(String property)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(property));
            }
        }
        #endregion
    }
}
